home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Toolbox / Visual Basic Toolbox (P.I.E.)(1996).ISO / graphics / resnc / resnc.txt
Text File  |  1995-04-30  |  8KB  |  188 lines

  1. Ok guys/gals, here it is.  Basically, I'm going to show how I implemented a resource-only
  2. dll to hold bitmaps.  Then I'll talk about how to retrieve them, get their color tables,
  3. and basically how to use them once their alive and living in your RAM.  Um, also I'll talk
  4. about a technique I learned about from Mark Novisoff, founder of Microhelp in Georgia(you
  5. know Unistaller and all that), where you can store any files in one single file for a 
  6. resource depository. The reason for this is two-fold 1) one of you asked about storing
  7. AVI's and WAV's instead of bmp's and 2) it's VB specific and the API ()'s to retrieve bmp's
  8. from true a dll can not store WAV's and AVI's.  
  9.  
  10. So, off we go:
  11.     \  /
  12.    :-)===00            
  13.     /  \.
  14.  
  15. PHASE I: Creating the DLL___________________________________________________________________
  16.  
  17.  
  18. This is the your source file.
  19. %%%%%%%%%%%%%%%%%MyResOnlyDll.C%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  20. //Resource only dll
  21. #include <windows.h>
  22.  
  23. //Declare the Windows-callable WindowsExitProcedure()
  24. int FAR PASCAL _export WEP (int nParam);
  25.  
  26. //This is the DLL's entry point, in the eye's of Windows
  27. int FAR PASCAL LibMain (HANDLE hInstance, WORD wDataSeg, 
  28.             WORD wHeapSize, LPSTR lpszCmdLine)
  29. {
  30.     if (wHeapSize > 0)
  31.         UnlockData(0);    //This unlock's the dll's data segment
  32.                 //and is required
  33.     return 1;        //Then it returns 1 to Windows, saying all is well
  34. }
  35.  
  36. //This is called by Windows when the dll's refernce count is = 0
  37. //or more simply when the dll is unloaded by you.  If you want to 
  38. //know about reference count's read about it in the SDK, it's somewhere
  39. //in there :)
  40. int FAR PASCAL _export WEP (int nParam)
  41. {
  42.     return 1;        //Just return 1 and Windows handles the rest
  43. }
  44. //Oh yea, get used to the reference count methodology, it is how
  45. //OLE manages the lifespan of an object too.  
  46.  
  47.  
  48. Ok, this code gives you all you need for the main dll body code. It 
  49. provided a way for Windows to say hello, do initialization if you need to, and then 
  50. a way to say goodbye, do de-initialization if you need to.
  51. %%%%%%%%%%%%%%%%%%%%End of MyResOnlyDll.C%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  52.  
  53.  
  54.  
  55. Then you need a module definition file.  And here's the skeleton code for it.
  56. %%%%%%%%%%%%%%%%%%%%MyResOnlyDll.def%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  57. //Resource only DLL
  58. LIBRARY        MODNAME //Name your module
  59. DESCRIPTION    'Put a description here for your module'
  60. EXETYPE        WINDOWS
  61. CODE        PRELOAD MOVEABLE DISCARDABLE
  62. DATA        PRELOAD MOVEABLE SINGLE
  63. %%%%%%%%%%%%%%%%%%%%End of MyResOnlyDll.def%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  64.  
  65.  
  66.  
  67. Ok, we've got the main dll body code done, the module's definition defined and now here's
  68. how to #include your bitmap's.
  69. %%%%%%%%%%%%%%%%%%%%MyResOnlyDll.rc%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  70. 1 BITMAP bitmap1.bmp    //Or use a full path 'c:\\graphics\\bmps\\bitmap1.bmp'
  71. 2 BITMAP bitmap2.bmp
  72. %%%%%%%%%%%%%%%%%%%%End MyResOnlyDll.rc%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  73.  
  74. Now build your dll.  That's it.  You've given your Visual C compiler all the necessary info
  75. to turn your bitmaps into one resource file.
  76.  
  77.  
  78.  
  79. PHASE II: Retrieving bitmaps in 256 colors from our DLL___________________________________
  80.  
  81. Now you've got a dll to load into memory and extract image's from.  The following is an 
  82. excerpt from some C code I wrote to load an image from my dll.
  83.     
  84.     if ((hLib = LoadLibrary("dllres.dll")) < 32)
  85.     {
  86.          DestroyWindow(hwnd);
  87.         return 0;
  88.     }
  89.                    
  90.     //Load DIBmp from dll
  91.     hRes = FindResource(hLib, MAKEINTRESOURCE(2), RT_BITMAP);
  92.     hGlobal = LoadResource(hLib, hRes);
  93.     lpbmi = (LPBITMAPINFOHEADER)LockResource(hGlobal);
  94.     
  95.     //Create palette from dib
  96.     hPal = CreateDIBPalette(lpbmi);        
  97.     hdc = GetDC(hwnd);
  98.     SelectPalette(hdc, hPal, FALSE);
  99.     RealizePalette(hdc);
  100.     
  101.     //check for non zero clrused member
  102.     if (lpbmi->biClrUsed)
  103.         iNumColors = (WORD)lpbmi->biClrUsed;  
  104.     else
  105.         iNumColors = 256;
  106.     hMyBmp = CreateDIBitmap(hdc, (LPBITMAPINFOHEADER)lpbmi,
  107.                 (LONG)CBM_INIT,
  108.                 (LPSTR)lpbmi + lpbmi->biSize + iNumColors *
  109.                 sizeof(RGBQUAD),
  110.                 (LPBITMAPINFO)lpbmi,
  111.                 DIB_RGB_COLORS);
  112.     ReleaseDC(hwnd, hdc);
  113.     UnlockResource(hGlobal);
  114.     FreeResource(hGlobal);
  115.  
  116. Starting from the top, here we go.  Basically, the only useful bitmaps these days are 
  117. 8bit or 256 color bitmaps.  So, the previous code compensates for this.  It does this by
  118. getting a pointer to the bitmap data in memory.  The FindRes, LoadRes and LockRes API calls
  119. are the sequence of calls that do this.  In the FindRes, the RT_BITMAP parameter tells
  120. Windows were loading a bitmap from this dll, so it knows how to extract the bitmap.  Now, we've
  121. got a pointer to bitmap in memory.  We can then 'walk' to its color table to create a palette
  122. compatible with bitmap.  Without, getting too far ahead of myself here's the code for creating
  123. this palette from my 8bit bitmap.  It could be adjusted simply to compensate for 16 bit and 24
  124. bit bitmaps.
  125.   
  126.  
  127.  
  128. HPALETTE CreateDIBPalette(LPBITMAPINFOHEADER lpbmi)
  129. {
  130.     LPBITMAPINFO    lpbi;
  131.     LPLOGPALETTE    lpPal;
  132.     HANDLE        hLogPal;
  133.     HPALETTE    hPal = NULL;
  134.     int        i, iColors;
  135.     
  136.     lpbi = (LPBITMAPINFO)lpbmi;    //convert to struct that has color info
  137.     if (lpbmi->biClrUsed)        //check the # of colors used by your bmp's
  138.         iColors = (WORD)lpbmi->biClrUsed;
  139.     else
  140.         iColors = 256;
  141.     
  142.     
  143.     hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE) +
  144.                 sizeof(PALETTEENTRY) * iColors);
  145.     lpPal = (LPLOGPALETTE)GlobalLock(hLogPal);
  146.     lpPal->palVersion = 0x300;
  147.     lpPal->palNumEntries = iColors;
  148.     
  149.     for (i = 0; i < iColors; i++)
  150.         {
  151.          lpPal->palPalEntry[i].peRed = lpbi->bmiColors[i].rgbRed;
  152.          lpPal->palPalEntry[i].peGreen = lpbi->bmiColors[i].rgbGreen;
  153.          lpPal->palPalEntry[i].peBlue = lpbi->bmiColors[i].rgbBlue;
  154.          lpPal->palPalEntry[i].peFlags = 0;
  155.          }
  156.     hPal = CreatePalette(lpPal);
  157.     GlobalUnlock(hLogPal);
  158.     GlobalFree(hLogPal);
  159.     
  160.     return hPal;
  161. }
  162.  
  163.  
  164. So, we get a long pointer to a bitmapinfoheader structure for our bitmap.  I check the structure
  165. for the number of colors actually used by the bitmap.  This isn't always 256 for an 8 bit bmp. 
  166. It could be anything <= 256.  Once I got that, I then allocate enough memory to hold a palette
  167. of this resolution in memory.  I then GlobalLock it to get a pointer to this memory.  Now, I can
  168. start initializing this memory.  The lpPal->palVersion = hex 300 is required.  Then, I read
  169. from the bitmap's structure, its color information into the logical palette.  Once,
  170. I've filled the logical palette with color values I call CreatePalette to actually get a handle
  171. to the palette for future API calls.  Then Unlock and Free the logical palette and return to
  172. the caller the handle to this particular DIB's palette.  
  173.  
  174.  
  175. Now, if you look at the code from above we can then use this palette to set up a memDC in which
  176. we select this palette and then call CreateDIBitmap to actually create a ***device dependent 
  177. bitmap****.  Once you have a DDB, you then BitBlt to the screen or whatever you want.  
  178.  
  179.  
  180. The bitmaps included in this zip file show how to create an indexed file to hold any type of
  181. information.  In the example, the author shows how to fill the file with bitmaps, but you 
  182. could put .AVI's or .WAV's in there.  
  183.  
  184. So, I hope all this was useful, I would have liked to put in a .hlp format but I just don't 
  185. have the time.  Anyway, I hope this helps.  Sorry it took so darn long.
  186.  
  187. Chris Douglass
  188. Imagesoft